/*********************************************************************** 
* 
*               High Speed AMBA Bus (AHB) Interface Example 
*                   for "QuickMIPS" QL901M-680 Device 
*                              ahb_master.v 
* 
*                          Copyright (c) 2002 
*                           QuickLogic, Corp. 
*																			    
* 
************************************************************************/ 
// First Draft (5/14/2002 H. Kim) 
 
`timescale 1ns/10ps 
 
module master2
   ( 
     // AHB Master Interface 
     clk, 
     reset, 
     HREADY, 
     HRESP, 
     hbusreq_o, 
     HTRANS, 
     HWRITE, 
     HSIZE, 
     HBURST, 
     HADDR, 
     HWDATA, 
	  HRDATA
//    	 hgrant_i,  
// 	State Machine Interface 
//	 req_done, 
//	 rd_req, 
//	 wr_req, 
//	 FIFO Interface 
//  	dataout, 
//	 datain, 
//	 push, 
//	 pop, 
// 	From DMA Register           
//   	 src_addr, 
//    	dst_addr          
//	BLOCK_SIZE 
  ); 
 
parameter nofmaster = 0;
 
// AHB Interface 
 
input           clk;                // This clock times all bus transfers 
input           reset;             // AHB reset signal 
input           HREADY;           // when active indicates that 
                                    // a transfer has finished on the bus 
input      HRESP;            // transfer response from AHB Slave 
                                    // (OKAY,ERROR,RETRY,SPLIT) 
//input           hgrant_i;           // bus grant from AHB Arbiter 
 
output          hbusreq_o;          // bus request to AHB Arbiter 
output  [1:0]   HTRANS;           // type of current transfer 
output          HWRITE;           // type of current transfer 
                                    // (NONSEQ,SEQ,IDLE,BUSY) 
output  [1:0]   HSIZE;            // size of current transfer 
output  [2:0]   HBURST;           // Burst type 
output  [31:0]  HADDR;            // Address out onto AHB for Rd/Wr 
output [31:0]   HWDATA;           // Write data out to AHB for Rx  
input  [31:0]   HRDATA;           // Read data from AHB for Tx 
 
	// State Machine Interface 
//output		req_done; 
//input	 		rd_req; 
//input			wr_req; 
 
	// FIFO Interface 
//output	[31:0]  dataout;			// Data Out to Read FIFO 
//input	[31:0]	datain;				// Data In from Write FIFO 
//output	 		push; 
//output			pop; 
 
    // From DMA Register           
//input	[31:0]  src_addr; 
//input	[31:0]  dst_addr;           
//input	[4:0]	BLOCK_SIZE; 
 
wire [1:0] HRESP2; 
wire hgrant_i;
assign hgrant_i = HREADY;

reg	[31:0]  src_addr; 
reg	[31:0]  dst_addr; 
wire              hbusreq_o; 
reg               HWRITE; 
wire   [1:0]      HSIZE; 
reg    [1:0]      HTRANS; 
reg    [2:0]      HBURST; 
wire  [31:0]      HADDR; 
reg   [31:0]      HWDATA; 
 
wire			req_done; 
reg		[4:0]	word_count; 

reg 	[31:0]	datain;
wire				pop; 
reg				push; 
wire	[31:0]  	dataout;			// Data Out to Read FIFO 
 
// Internal register declarations 
reg    [3:0]      ahb_master_state;     // AHB Master I/F S/M State bits 
reg    [3:0]      state_prev_clk;       // AHB Master I/F S/M State bits 
                                        // delayed by 1-clock 
 
reg               latch_addr;           // used to latch address from fifo 
                                        // into address incrementer 
// reg               latch_prevaddr;       // used to restore the prev. addr 
                                        // in case of RETRY/SPLIT 
wire              lastbrstrd;           // Last Burst Read 
wire              lastbrstwr;           // Last Burst Read 
reg				  burstwrflag_last_n; 
reg    [29:0]      haddr_reg;            // upper 30-bits of HADDR 
wire   [29:0]      nextaddr;             // upper 30-bits of HADDR 
reg    [29:0]      haddr_prev;           // lower address bits of the previous 
                                        // transfer.  Used to restore address 
                                        // in case of RETRY/SPLIT 
reg               ahm_busreq_reg;       // AHB registered request signal 
                                        // used with busreq_comb to generate 
                                        // ahm_busreq O/P to AHB arbiter 
reg               rddf_wren;            // enables/disables data fifo 
                                        // write logic 
reg               busreq_prev;          // AHB access request signal delayed 
reg               busreq_comb; 

reg	 		rd_req; 
reg			wr_req; 

reg [31:0]ramToWriteFromSlave[0:9];
reg [31:0]ram[0:9];
reg [3:0] counter = 4'b0,counter2=4'b0;


parameter         BLOCK_SIZE     =  5'd10;
 
// ****************************************************** 
// AHB Master Interface State Machine Encoding 
// ****************************************************** 
parameter         AHM_IDLE       =  4'b0000; 
parameter         AHM_BREQ       =  4'b0001; 
parameter         AHM_NSEQWR     =  4'b0010; 
parameter         AHM_SEQWR      =  4'b0011; 
parameter         AHM_WRWAIT     =  4'b0101; 
parameter         AHM_RETRY      =  4'b0110; 
parameter         AHM_LASTWR     =  4'b0111; 
parameter         AHM_GOIDLE     =  4'b1000; 
parameter         AHM_NSEQRD     =  4'b1001; 
parameter         AHM_SEQRD      =  4'b1010; 
parameter         AHM_RDWAIT     =  4'b1011; 
parameter         AHM_LASTRD     =  4'b1101; 
 
 
// ****************************************************** 
// Parameter Definition for AHB Transfer Type(HTRANS) 
// ****************************************************** 
parameter         IDLE                = 2'b00; 
parameter         BUSY                = 2'b01; 
parameter         NONSEQ              = 2'b10; 
parameter         SEQ                 = 2'b11; 
   
// ****************************************************** 
// Parameter Definition for AHB Transfer Type(HBURST) 
// ****************************************************** 
parameter         SINGLE              = 3'b000; 
parameter         INCR                = 3'b001; 
parameter         INCR4               = 3'b011; 
parameter         INCR8               = 3'b101; 
parameter         INCR16              = 3'b111; 
   
// ****************************************************** 
// Parameter Definition for AHB Transfer SIZE(HSIZE) 
// ****************************************************** 
parameter         BYTE                = 2'b00; 
parameter         HALFWORD            = 2'b01; 
parameter         WORD                = 2'b10; 
   
// ****************************************************** 
// Parameter Definition for AHB Response Type(HRESP) 
// ****************************************************** 
parameter         OKAY                = 2'b00; 
parameter         ERROR               = 2'b01; 
parameter         RETRY               = 2'b10; 
parameter         SPLIT               = 2'b11; 
   
// ****************************************************** 
// Parameter Definition for AHB Write/Read Command (HWRITE) 
// ****************************************************** 
parameter         READ                = 1'b0; 
parameter         WRITE               = 1'b1; 
 
// ********************************************************** 
 
assign #2 dataout[31:0] = HRDATA; 
 
// ********************************************************** 
// AHB Master I/F State Machine 
// ********************************************************** 
 
assign HRESP2 = {1'b0,HRESP}; 
 
assign HSIZE = WORD;		   // Always WORD Transfer 
assign req_done = (word_count == 5'b00001) && (push || pop); 
 
always @(posedge clk or posedge reset) 
begin 
 
   if(reset) begin 
 
      ahm_busreq_reg    <= 1'b0; 
      HWRITE          <= READ; 
      latch_addr        <= 1'b0; 
      HBURST          <= SINGLE; 
//      HSIZE           <= WORD; 
      rddf_wren         <= 1'b0; 
//	  req_done			<= 1'b0; 
      ahb_master_state  <= AHM_IDLE; 
   end 
 
   // error does not exist or previously generated abort is cleared 
   else begin 
 
      case(ahb_master_state)   // synopsys full_case parallel_case 
 
         AHM_IDLE:  begin 
               if(rd_req) begin			// DMA Read Cycle 
                  // Assert bus access request to AHB Arbiter for read transfers 
                  ahm_busreq_reg    <= 1'b1; 
                  // assign the read/write command to indicate read cycle 
                  HWRITE          <= READ; 
                  // design supports only WORD reads 
//                  HSIZE           <= WORD; 
                  // latch current address from address fifo into 
                  // incrementer, output of which gets onto AHB 
                  // as transfer address 
                  latch_addr        <= 1'b1; 
                  ahb_master_state  <= AHM_BREQ; 
               end 
               else if(wr_req) begin	// DMA Write Cycle 
                  // Assert bus access request to AHB Arbiter 
                  ahm_busreq_reg    <= 1'b1; 
                  // assign the read/write command to indicate write cycle 
                  HWRITE          <= WRITE; 
                  // design supports only WORD reads 
//                  HSIZE           <= WORD; 
                  // latch current address from address fifo into 
                  // incrementer, output of which gets onto AHB 
                  // as transfer address 
                  latch_addr        <= 1'b1; 
                  ahb_master_state  <= AHM_BREQ; 
               end 
         end 
 
         // wait until bus is granted 
         AHM_BREQ:  begin 
               latch_addr          <= 1'b0; 
  //             latch_prevaddr      <= 1'b0; 
          //     if(hgrant_i & HREADY) begin       //den itan se sxolio
                  // write transfer 
                  if(HWRITE) begin 
                     ahb_master_state  <= AHM_NSEQWR; 
//                     HSIZE           <= hsize; 
                     // if it is single write cycle remove bus request 
                     // and assert HBURST to SINGLE 
                     if(wr_req && (word_count == 5'b00001)) begin 
                        ahm_busreq_reg <= 1'b0; 
                        HBURST       <= SINGLE; 
                     end 
                     // if it is intended burst then keep bus request 
                     // asserted and assert HBURST to INCR 
                     // (burst of undefined length) 
                     else begin 
                        HBURST       <= INCR; 
                     end 
                  end 
                  // read transfer 
                  else begin 
                     // read request is single 
                     if (rd_req && (word_count == 5'b00001)) begin 
                        HBURST          <= SINGLE; 
                        ahm_busreq_reg    <= 1'b0; 
                     end 
                     else begin 
                        HBURST          <= INCR; 
                     end 
                     // read request is single 
                     ahb_master_state    <= AHM_NSEQRD; 
                  end 
               
         end 
         // first address phase of read transfer 
         AHM_NSEQRD:  begin 
				// Target is ready accept data 
               if(HREADY) begin 
                  // If it is single read cycle(HBURST == SINGLE) OR 
                  // only one more data left from current read burst 
                  // (rdbrst_compl) OR 
                  // current data phase at 1k page boundary 
                  // (pgbndry | init_pgboundry) 
                  // go to WAIT(until data phase completes) as current data 
                  // is last data phase 
                  // if data fifo is almost full(it can take only one more data) 
                  // terminate the burst read cycle on AHB 
                  if(HBURST == SINGLE) begin 
                     ahb_master_state    <= AHM_RDWAIT; 
                  end 
                  // more data to be read but grant is lost 
                  // can't continue the burst beyond the current data phase 
                  else if(~hgrant_i) begin 
                     ahb_master_state    <= AHM_LASTRD; 
                  end 
                  // continue to read 
                  else begin 
                     if(lastbrstrd) begin 
                        ahm_busreq_reg      <= 1'b0; 
                     end 
                     ahb_master_state    <= AHM_SEQRD; 
                  end 
                  // enable data fifo write logic 
                     rddf_wren           <= 1'b1; 
               end 
         end 
         // consecutive transfers of burst read 
         AHM_SEQRD:  begin 
               // target is ready to provide data 
               if(HREADY & HRESP2[0] == OKAY) begin 
                  if(HTRANS == IDLE) begin 
                     ahb_master_state    <= AHM_GOIDLE; 
                     ahm_busreq_reg      <= 1'b0; 
                     rddf_wren           <= 1'b0; 
                  end 
                  // only one more data left from current read burst 
                  else if(lastbrstrd) begin  
                     ahb_master_state    <= AHM_RDWAIT; 
                     ahm_busreq_reg      <= 1'b0; 
                  end 
                  else if(~hgrant_i) begin 
                     ahb_master_state    <= AHM_LASTRD; 
                     if(~busreq_comb) begin 
                        ahm_busreq_reg      <= 1'b0; 
                     end 
                  end 
               end 
               // system needs to be reset 
               else if(~HREADY & HRESP2 == ERROR) begin 
                  rddf_wren           <= 1'b0; 
                  ahb_master_state    <= AHM_IDLE; 
                  ahm_busreq_reg      <= 1'b0; 
               end 
               else begin 
                  // enable as long as in SEQRD state 
                     rddf_wren           <= 1'b1; 
                  if(~busreq_comb) begin 
                     ahm_busreq_reg      <= 1'b0; 
                  end 
               end 
         end 
         // last read data phase from current read transfer 
         // (due to lost ownership of address bus) 
         // once the current data phase is over(successful or not(retry/split)) 
         // master rearbitrates and starts with non-sequential again 
         AHM_LASTRD:  begin 
               // target is ready to accept data 
               if(HREADY & HRESP2 == OKAY) begin 
                  ahm_busreq_reg      <= 1'b1; 
                  ahb_master_state    <= AHM_BREQ; 
                  rddf_wren           <= 1'b0; 
               end 
               else if(~HREADY & (HRESP2 == RETRY | HRESP2 == SPLIT) ) begin 
                  ahm_busreq_reg      <= 1'b1; 
                  ahb_master_state    <= AHM_BREQ; 
 //                 latch_prevaddr      <= 1'b1; 
                  rddf_wren           <= 1'b0; 
               end 
               // error indicated on AHB 
               // in current design it is unrecoverable 
               // system needs to be reset 
               else if(~HREADY & HRESP2 == ERROR) begin 
                  rddf_wren           <= 1'b0; 
                  ahb_master_state    <= AHM_IDLE; 
                  ahm_busreq_reg      <= 1'b0; 
               end 
               else begin 
                  rddf_wren           <= 1'b1; 
               end 
         end 
         // first address phase of write transfer 
         AHM_NSEQWR:  begin 
               if(HREADY) begin 
                  // If it is single write cycle go to WAIT as 
                  // current data is last data phase 
                  if (HBURST == SINGLE) begin 
                     ahb_master_state    <= AHM_WRWAIT; 
                  end 
                  else if(~hgrant_i) begin 
                     ahb_master_state    <= AHM_LASTWR; 
                  end 
                  else begin 
                     ahb_master_state    <= AHM_SEQWR; 
                  end 
               end 
         end 
         // data phase of either single read cycle 
         // or last data phase of burst read cycle 
         AHM_RDWAIT:  begin 
               // target is ready 
               if(HREADY == 1'b1 & HRESP2 == OKAY) begin 
                  ahb_master_state    <= AHM_GOIDLE; 
//	  				req_done			<= 1'b1; 
                  // disable data fifo write logic 
                  rddf_wren           <= 1'b0; 
                  // read the address fifo as it is last data phase 
                  // so that application can strobe new cycle if any 
                  ahm_busreq_reg      <= 1'b0; 
               end 
               else if(~HREADY & (HRESP2 == RETRY | HRESP2 == SPLIT) ) begin 
                     ahb_master_state    <= AHM_BREQ; 
                     ahm_busreq_reg      <= 1'b1; 
                  // disable data fifo write logic 
                  rddf_wren           <= 1'b0; 
//                  latch_prevaddr      <= 1'b1; 
               end 
               // error indicated on AHB 
               // in current design it is unrecoverable 
               // system needs to be reset 
               else if(~HREADY & HRESP2 == ERROR) begin 
                  ahb_master_state    <= AHM_IDLE; 
                  ahm_busreq_reg      <= 1'b0; 
               end 
         end 
         // last data phase of write transfer(single/burst) 
         // if successful S/M goes to idle 
         // if unsuccessful(RETRY/SPLIT) transfer is retried 
         AHM_WRWAIT:  begin 
               // target is ready 
               if(HREADY == 1'b1 & HRESP2 == OKAY) begin 
                  ahb_master_state    <= AHM_GOIDLE; 
                  ahm_busreq_reg      <= 1'b0; 
//	  				req_done			<= 1'b1; 
               end 
               else if(~HREADY & (HRESP2 == RETRY | HRESP2 == SPLIT) ) begin 
                  ahb_master_state    <= AHM_BREQ; 
                  ahm_busreq_reg      <= 1'b1; 
//                  latch_prevaddr      <= 1'b1; 
               end 
               // system needs to be reset 
               else if(~HREADY & HRESP2 == ERROR) begin 
                  ahb_master_state    <= AHM_IDLE; 
                  ahm_busreq_reg      <= 1'b0; 
               end 
         end 
         // sub-sequent address/data phases of burst write cycle 
         AHM_SEQWR:                 // target is ready to accept data 
               if(HREADY & HRESP2 == OKAY) begin 
                  if(HTRANS == BUSY) begin 
                        HBURST          <= INCR; 
                     if(hgrant_i) begin 
                        ahb_master_state    <= AHM_NSEQWR; 
                     end 
                     else begin 
                        ahb_master_state    <= AHM_BREQ; 
                     end 
                  end 
                  else if(HTRANS == IDLE) begin 
                     ahb_master_state    <= AHM_GOIDLE; 
                     // read the address fifo as it is last data phase 
                     // so that application can strobe new cycle if any 
                     ahm_busreq_reg      <= 1'b0; 
                  end 
				// Finish cycle when last word is written 
                  else if(lastbrstwr) begin 
                     ahm_busreq_reg      <= 1'b0; 
                     ahb_master_state    <= AHM_LASTWR; 
                  end   
                  // grant lost while waiting for transfer to finish 
                  else if(~hgrant_i) begin 
                     ahb_master_state    <= AHM_LASTWR; 
                  end 
			   end 
               else if(~HREADY & (HRESP2 == RETRY | HRESP2 == SPLIT) ) begin 
                  ahb_master_state    <= AHM_BREQ; 
                  ahm_busreq_reg      <= 1'b1; 
 //                 latch_prevaddr      <= 1'b1; 
               end 
               // error indicated on AHB 
               // in current design it is unrecoverable 
               // system needs to be reset 
               else if(~HREADY & HRESP2 == ERROR) begin 
                  ahb_master_state    <= AHM_IDLE; 
                  ahm_busreq_reg      <= 1'b0; 
               end 
         // last data phase of write transfer because of lost ownership 
         // of address bus(Grant lost) 
         // once current data phase completes(successful or not(retry/split)) 
         // master re-arbitrates and resumes pending cycle starting with 
         // non-sequential 
         AHM_LASTWR:  begin 
               // target is ready to accept data 
               if(HREADY & HRESP2 == OKAY) begin 
                  // if the current data is last data from current burst 
                  // goto idle, emptying the address fifo 
                  if(burstwrflag_last_n) begin 
                     ahb_master_state    <= AHM_GOIDLE; 
                     // read the address fifo as it is last data phase 
                     // so that application can strobe new cycle if any 
                     ahm_busreq_reg      <= 1'b0; 
                  end 
                  else begin 
                     ahm_busreq_reg      <= 1'b1; 
                     ahb_master_state    <= AHM_BREQ; 
                  end 
               end 
 
               else if(~HREADY & (HRESP2 == RETRY | HRESP2 == SPLIT) ) begin 
                  // assert appropriate flag to be used to generate 
                  // hburst signal in retried transaction 
                  // intended transfer would be complete(last data phase) 
                  // if it was not retried(so only one more data left) 
                  ahm_busreq_reg      <= 1'b1; 
                  ahb_master_state    <= AHM_BREQ; 
//                  latch_prevaddr      <= 1'b1; 
               end 
               // error indicated on AHB 
               // in current design it is unrecoverable 
               // system needs to be reset 
               else if(~HREADY & HRESP2 == ERROR) begin 
                  ahb_master_state    <= AHM_IDLE; 
                  ahm_busreq_reg      <= 1'b0; 
               end 
         end 
         // master re-arbitrates as it lost grant in the middle of transfer 
         // it waits until data fifos are available 
         AHM_RETRY:  begin 
//               latch_prevaddr         <= 1'b0; 
                  ahm_busreq_reg      <= 1'b1; 
                  ahb_master_state    <= AHM_BREQ; 
         end 
         // this state provides time to read address fifo before 
         // entering idle state 
         AHM_GOIDLE:  begin 
               ahb_master_state    <= AHM_IDLE; 
         end 
      endcase 
   end 
end 
 
// AHB write burst flag latching 
always @(posedge clk or posedge reset) 
begin 
   if(reset) begin 
      burstwrflag_last_n  <= 1'b1; 
   end 
   else begin //bug fix - illusion of last phase in the burst  
      if(pop | (ahb_master_state == AHM_IDLE)) begin 
         burstwrflag_last_n  <= (word_count == 5'b00001); 
      end 
   end 
end 
 
// latching state  
always @(posedge clk or posedge reset) 
begin 
   if(reset) begin 
      state_prev_clk      <= AHM_IDLE; 
   end 
   else begin 
      if(HREADY) begin 
         state_prev_clk      <= ahb_master_state; 
      end 
   end 
end 
 
// address generation 
always @(posedge clk or posedge reset) 
begin 
   if(reset) begin 
      haddr_reg[29:0]      <= 30'h0000_0000; 
      haddr_prev[29:0]     <= 30'h0000_0000; 
   end 
   else if(latch_addr && rd_req) begin 
         haddr_reg[29:0]      <= src_addr[31:2];  
         haddr_prev[29:0]     <= src_addr[31:2]; 
   end 
   else if(latch_addr && wr_req) begin 
         haddr_reg[29:0]      <= dst_addr[31:2];  
         haddr_prev[29:0]     <= dst_addr[31:2];  
   end 
   else begin 
        if( ahb_master_state == AHM_NSEQWR | 
             ahb_master_state == AHM_SEQWR | 
             ahb_master_state == AHM_NSEQRD |  
             ahb_master_state == AHM_SEQRD) begin 
            if(HREADY & HRESP2 == OKAY & HTRANS != BUSY ) begin  
               haddr_reg[29:0]      <= nextaddr[29:0]; 
               haddr_prev[29:0]     <= HADDR[31:2]; 
            end 
         end 
   end 
end 
// address generation 
always @(posedge clk or posedge reset) 
begin 
   if(reset) begin 
         word_count			  <= 5'b00000;  
   end 
   else if(latch_addr && rd_req) begin 
         word_count			  <= BLOCK_SIZE;  
   end 
   else if(latch_addr && wr_req) begin 
         word_count			  <= BLOCK_SIZE;  
   end 
   else if (push | pop) begin 
         word_count			  <= word_count - 1;  
   end 
end 


// Final address that gets onto AHB for Read/Write transfers  
assign HADDR[31:0]    = (nofmaster==0) ? {haddr_reg[29:0], 2'b00} :  // master0->slave0
					  (nofmaster==1) ? {3'b001,haddr_reg[26:0], 2'b00} :  // master1->slave1
					  {3'b010,haddr_reg[26:0], 2'b00}; //allios 2         // master2->slave2
					  
			 
 
 
// address of next transfer used by address incrementer 
assign nextaddr[29:0]  = haddr_reg[29:0] + 1; 
 
assign #1 pop = (ahb_master_state == AHM_SEQWR | ahb_master_state == AHM_NSEQWR) 
						&& HREADY && (HRESP2 == OKAY); 
 
// DMA Tx fifo write strobe logic 
always @(rddf_wren or HREADY or HRESP2) 
begin 
   if(HREADY == 1'b1 & HRESP2 == OKAY) begin 
      if(rddf_wren) begin 
         push = 1'b1; 
      end 
      else begin 
         push = 1'b0; 
      end 
   end 
   else begin 
      push = 1'b0; 
   end 
end	  
 
// HTRANS generation logic 
// input signal dependencies removed to avoid combinitorial path 
// thru the core input signals 
// Fix_041601_Rev1.0b_10 
//always @(ahb_master_state or hsize_chg or burstwrflag_last_n or 
//         busreq_prev or HREADY or HRESP2 
//        ) 
always @(ahb_master_state or busreq_prev) 
begin 
   case (ahb_master_state) 
      AHM_SEQWR : begin 
               HTRANS = SEQ; 
      end 
      AHM_NSEQWR, AHM_NSEQRD : begin 
         HTRANS = NONSEQ; 
      end 
      AHM_SEQRD : begin 
         // input signal dependencies removed to avoid combinitorial path 
         // thru the core input signals 
         // Fix_041601_Rev1.0b_10 
         //if(HREADY == 1'b1 & HRESP2 == OKAY) begin 
            if(~busreq_prev) begin 
               HTRANS = IDLE; 
            end 
            else begin 
               HTRANS = SEQ; 
            end 
        end 
      default : begin 
         HTRANS = IDLE; 
      end 
   endcase 
end 
 
// removing bus request signal at the beginning of last data phase 
// of SEQWR 
// input signal dependencies removed to avoid combinitorial path 
// thru the core input signals 
// Fix_041601_Rev1.0b_10 
//always @(ahb_master_state or ai_wrdfrd_n or burstwrflag_n or 
//         rddf_second_last_n or HTRANS or 
//         HREADY or HRESP2 or pgbndry) 
always @(ahb_master_state or HTRANS) 
begin 
   if(ahb_master_state == AHM_SEQWR) begin 
      if( HTRANS == IDLE ) begin 
         busreq_comb = 1'b0; 
      end 
      else begin 
         busreq_comb = 1'b1; 
      end 
   end 
   else if(ahb_master_state == AHM_SEQRD) begin 
      // input signal dependencies removed to avoid combinitorial path 
      // thru the core input signals 
      // Fix_041601_Rev1.0b_10 
      //if(HREADY == 1'b1 & HRESP2 == OKAY) begin 
         if(HTRANS == IDLE) begin 
            busreq_comb = 1'b0; 
         end 
         else begin 
            busreq_comb = 1'b1; 
         end 
   end 
   else begin 
      busreq_comb = 1'b1; 
   end 
end 
 
 
// final AHB access request signal to arbiter 
assign hbusreq_o = ahm_busreq_reg; 

 
// AHB write data generation 
always @(posedge clk or posedge reset) 
begin 
   if(reset) begin 
      HWDATA[31:0]        <= 32'h0000_0000; 
   end 
   else if(pop == 1'b1) begin 
         HWDATA[31:0]     <= datain[31:0]; 
   end 
end 
 
assign lastbrstrd   = push && (word_count == 5'b00010); 
assign lastbrstwr   = pop && (word_count == 5'b00001); 
 

// delayed version of hbusreq_o 
// used in HTRANS generation logic 
always @(posedge clk or posedge reset) 
begin 
   if(reset) 
      busreq_prev <= 1'b0; 
   else 
      busreq_prev <= hbusreq_o; 
end 




	//***************** request LOGIC for read kai write *****************//	
	reg writeFinished =0;


	always@(posedge clk or posedge reset) begin
		if (reset) begin
			wr_req = 0;
			rd_req = 0;
			writeFinished =0;
		end
		else 	if (counter2>=10) begin
				wr_req = 0;
				rd_req = 0;
		end
		else if (~req_done ) begin
			if (writeFinished) begin //epeita diavase ta (then read what you wrote before)
				wr_req = 0;
				rd_req = 1;	
			end
			else begin //arxika grapse ston slave (write to slave)
				rd_req = 0;
				wr_req = 1;

			end
		end
		else  begin
				writeFinished =1;
				wr_req = 0;
				rd_req = 0;
		end		
	end	


	//***************** FIFO LOGIC *****************//	
	

	
	always @ (*)
		datain=ram[counter];

	always @(posedge clk) begin
		if (reset) begin
			counter=0;
			dst_addr=0;
		end
		else if ( pop == 1  && HTRANS[1] ) begin
			counter=counter+1;
			if (counter>=10) counter=0;
		end
	end
	
	always @(*)
		if (HREADY)//(counter2 < 4'd10)
			ramToWriteFromSlave[counter2]=dataout;
	
	always @(posedge clk) begin
	//	if (counter2>=10) counter2=0;
		if (reset) begin
			counter2=0;
			src_addr=0;
		end
		else if (push && counter2<10) begin
			counter2=counter2+1;
		end
	end
		

	//***************** RAMs *****************//				  
			

	always @(posedge clk) begin
	      if (reset) begin
		  ramToWriteFromSlave[0] = 32'b0;
		  ramToWriteFromSlave[1] = 32'b0;
		  ramToWriteFromSlave[2] = 32'b0;
		  ramToWriteFromSlave[3] = 32'b0;
		  ramToWriteFromSlave[4] = 32'b0;
		  ramToWriteFromSlave[5] = 32'b0;
		  ramToWriteFromSlave[6] = 32'b0;
		  ramToWriteFromSlave[7] = 32'b0;
		  ramToWriteFromSlave[8] = 32'b0;
		  ramToWriteFromSlave[9] = 32'b0;
	      end
	end
	
	


	always @(posedge clk) begin
		  if (reset) begin
		    if (nofmaster==0) begin
			    ram[0] = 32'h100;
			    ram[1] = 32'h101;
			    ram[2] = 32'h102;
			    ram[3] = 32'h103;
			    ram[4] = 32'h104;
			    ram[5] = 32'h105;
			    ram[6] = 32'h106;
			    ram[7] = 32'h107;
			    ram[8] = 32'h108;
			    ram[9] = 32'h109;
		    end
		    else if (nofmaster==1) begin
			    ram[0] = 32'h110;
			    ram[1] = 32'h111;
			    ram[2] = 32'h112;
			    ram[3] = 32'h113;
			    ram[4] = 32'h114;
			    ram[5] = 32'h115;
			    ram[6] = 32'h116;
			    ram[7] = 32'h117;
			    ram[8] = 32'h118;
			    ram[9] = 32'h119;
		    end
		    else begin
			    ram[0] = 32'h120;
			    ram[1] = 32'h121;
			    ram[2] = 32'h122;
			    ram[3] = 32'h123;
			    ram[4] = 32'h124;
			    ram[5] = 32'h125;
			    ram[6] = 32'h126;
			    ram[7] = 32'h127;
			    ram[8] = 32'h128;
			    ram[9] = 32'h129;
		    end
		end
	end				  
					  
					  
endmodule 

 
